package com.sina.finance.api.framework.utils;


import com.sina.finance.api.framework.constants.ErrorCodeConstants;
import com.sina.finance.api.framework.validator.ConditionException;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import static com.sina.finance.api.framework.constants.ErrorCodeConstants.REQUIRED_PARAMETER;

/**参数解析器**/
public class ParameterParser {

	private static ConversionService conversionService = new CustomConversionService();

	private Map<String, String[]> params;
	
	private ParameterParser(Map<String, String[]> params){
		this.params = params;
	}
	

	/**获取一个参数解析器的实例**/
	public static ParameterParser createInstance(Map<String, String[]> params){
		return new ParameterParser(params);
	}

	/**获取原始的参数Map**/
	public Map<String, String[]> getParameterMap(){
		return params;
	};

	/**根据参数名称获取字符型参数值，参数不存在则返回null**/
	public String getString(String paramName){
		return getValue(paramName, String.class);
	}

	/**根据参数名称获取长整形参数值，参数不存在则返回null**/
	public Long getLong(String paramName){
		return getValue(paramName, Long.class);
	}

	/**根据参数名获取BigDecimal对象，参数之不存在或值为null返回0**/
	public BigDecimal getBigDecimal(String paramName){
		return getValue(paramName, BigDecimal.class);
	}

	public String getString(String paramName, boolean nullable){
		return this.getValue(paramName, String.class, nullable);
	}

	public Long getLong(String paramName, boolean nullable){
		return this.getValue(paramName, Long.class, nullable);
	}

	public BigDecimal getBigDecimal(String paramName, boolean nullable){
		return this.getValue(paramName, BigDecimal.class, nullable);
	}

	/**检查params中获取paramName对应的value数组, 如果不存在对应数组或数组为空则抛出异常
	 * @deprecated 请使用getString(paramName,false), getLong(paramName,false)...或getValue(paramName,false)进行空值检测并可以直接返回需要的类型
	 * **/
	public void checkNull(String paramName){
		getString(paramName, false);
	}

	public Date getDate(String paramName) {
		return this.getValue(paramName, Date.class);
	}

	public Date getDate(String paramName, boolean nullable) {
		return this.getValue(paramName, Date.class, nullable);
	}



	public <T> T getValue(String paramName, Class<T> targetType, boolean nullable) {

		String[] values = params.get(paramName);

		int length = ArrayUtils.getLength(values);

		// 未传递参数 || 参数值为空
		if(length < 1 || StringUtils.isBlank(values[0])){
			if (!nullable) {
				throw new ConditionException(REQUIRED_PARAMETER, String.format("参数[%s]不能为空", paramName));
			}
			return null;
		} else if (length == 1) {
			try {
				return conversionService.convert(values[0], targetType);
			} catch (ConversionException e) {
				throw new ConditionException(ErrorCodeConstants.SYS_ERROR_CODE_S16, String.format("参数[%s]格式非法", paramName));
			}
		} else {
			if (targetType.isArray()) {
				try {
					return conversionService.convert(values, targetType);
				} catch (ConversionException e) {
					throw new ConditionException(ErrorCodeConstants.SYS_ERROR_CODE_S16, String.format("参数[%s]格式非法", paramName));
				}
			} else {
				throw new RuntimeException("参数的个数大于1, 参数名:" + paramName);
			}
		}
	}

	public <T> T getValue(String paramName, Class<T> targetType) {

		return this.getValue(paramName, targetType, true);
	}



	public static void main(String[] args) {
		System.out.println(int[].class.isArray());
	}


}
